/*
 * Copyright (C) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#[cfg(any(test, feature = "test-utils"))]
pub mod test_utils {
    use super::*;
    use mockall::*;
    
    use crate::common::constants::*;
    use crate::common::types::*;
    use crate::entry::user_auth_ffi::CommandId;
    use crate::traits::{
        logger::{Logger, LoggerRegistry, LogLevel},
        executor_manager::{MockExecutorManager, ExecutorManagerRegistry},
        user_db_manager::{MockUserDbManager, UserDbManagerRegistry, User, Credential, CredentialFilter},
        misc_manager::{MockMiscManager, MiscManagerRegistry, TokenKey},
        command_manager::{CommandManager, CommandManagerRegistry, CommandHandler},
        crypto_engine::{MockCryptoEngine, CryptoEngineRegistry, KeyPair},
        storage_io::{MockStorageIo, StorageIo, StorageIoRegistry, StorageType},
        config_manager::{MockConfigManager, ConfigManagerRegistry},
        time_keeper::{MockTimeKeeper, TimeKeeper, TimeKeeperRegistry},
        edit_session_manager::{EditSessionManagerRegistry},
        context_manager::{ContextManager, ContextManagerRegistry, AuthContext, EnrollContext},
        event_manager::{MockEventManager, EventManagerRegistry, Event},
        auth_policy_manager::{MockAuthPolicyManager, AuthPolicyManagerRegistry, AuthPolicy},
    };
    use crate::{Box, Vec};

    // Test Logger implementation
    pub struct TestLogger;

    impl TestLogger {
        pub fn new() -> Self {
            TestLogger
        }
    }

    impl Logger for TestLogger {
        fn log(&self, level: LogLevel, file_name: &str, line_num: u32, args: core::fmt::Arguments<'_>) {
            println!("[LOG] [{:?}] [{}:{}] {}", level, file_name, line_num, args);
        }
    }

    pub struct UtRegistryGuard {
    }

    impl UtRegistryGuard {
    pub fn new() -> Self {
        let mock_logger = TestLogger::new();
        LoggerRegistry::set(Box::new(mock_logger));

        let mock_executor_manager = MockExecutorManager::new();
        ExecutorManagerRegistry::set(Box::new(mock_executor_manager));

        let mock_user_db_manager = MockUserDbManager::new();
        UserDbManagerRegistry::set(Box::new(mock_user_db_manager));

        let mock_misc_manager = MockMiscManager::new();
        MiscManagerRegistry::set(Box::new(mock_misc_manager));
        let mock_storage_io = MockStorageIo::new();
        StorageIoRegistry::set(Box::new(mock_storage_io));
        let mock_config_manager = MockConfigManager::new();
        ConfigManagerRegistry::set(Box::new(mock_config_manager));
        let mock_time_keeper = MockTimeKeeper::new();
        TimeKeeperRegistry::set(Box::new(mock_time_keeper));
        let mock_crypto_engine = MockCryptoEngine::new();
        CryptoEngineRegistry::set(Box::new(mock_crypto_engine));
        let mock_event_manager = MockEventManager::new();
        EventManagerRegistry::set(Box::new(mock_event_manager));
        let mock_auth_policy_manager = MockAuthPolicyManager::new();
        AuthPolicyManagerRegistry::set(Box::new(mock_auth_policy_manager));
        

        Self {}
    }
}

    impl Drop for UtRegistryGuard {
        fn drop(&mut self) {
            // 重置所有 registry 为默认实现
            LoggerRegistry::reset();
            ExecutorManagerRegistry::reset();
            UserDbManagerRegistry::reset();
            MiscManagerRegistry::reset();
            // CommandManagerRegistry::reset();  // Skip due to reference returns
            CryptoEngineRegistry::reset();
            StorageIoRegistry::reset();
            ConfigManagerRegistry::reset();
            TimeKeeperRegistry::reset();
            EventManagerRegistry::reset();
            AuthPolicyManagerRegistry::reset();
            // EditSessionManagerRegistry::reset();  // Skip due to reference returns
            // ContextManagerRegistry::reset();  // Skip due to reference returns
        }
    }
}

#[macro_export]
macro_rules! ut_registry_guard {
    () => {
        $crate::test_utils::trait_mocks::test_utils::UtRegistryGuard::new()
    };
}